Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MoveSCU implementation #108

Closed

Conversation

josepp-moreira
Copy link
Contributor

A command line interface for C-MOVE SCU.

@Enet4 Enet4 changed the title MOVESCU implementation Move CU implementation Mar 8, 2021
@Enet4 Enet4 changed the title Move CU implementation MoveSCU implementation Mar 20, 2021
Copy link
Owner

@Enet4 Enet4 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for working on this. The expectations of use are still a bit too off for the tool to enter the ecosystem. I have gathered the related comments below.

To create a query DICOM object file, you can follow the advice from DCMTK regarding findscu. This text file:

# query patient names and IDs
(0008,0052) CS [PATIENT]     # QueryRetrieveLevel
(0010,0010) PN []            # PatientsName
(0010,0020) LO [P123]            # PatientID

can be converted to a DICOM file with the DCMTK command dump2dcm. The file would then serve as input to this tool (in this example, to move all images of patient with the ID P123).

Other minor concerns are that this is still missing a readme file.

I would appreciate it if you could look into this in some of your spare time. Otherwise, I can put it in my backlog.

/// the called AE title
#[structopt(long = "called-ae-title", default_value = "ANY-SCP")]
called_ae_title: String,

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// the maximum PDU length

} = App::from_args();

if verbose {
println!("Establishing association with '{}'...", &addr);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

println! and other macros already borrow arguments implicitly.

Suggested change
println!("Establishing association with '{}'...", &addr);
println!("Establishing association with '{}'...", addr);

/// the DICOM file to store
file: PathBuf,
/// the C-MOVE destination
#[structopt(short = "mo", long = "move-destination", default_value = "")]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Short arguments longer than 1 character are not supported by clap.

In addition, I would say that empty string as the default value does not make much sense. The user has to provide a move destination, otherwise it is unclear where it should go.

Suggested change
#[structopt(short = "mo", long = "move-destination", default_value = "")]
#[structopt(long = "move-destination")]

let ts = TransferSyntaxRegistry
.get(&transfer_syntax)
.expect("Poorly negotiated transfer syntax");

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As of the established version of the association API, the client association no longer provides presentation_context_id, because it keeps all accepted presentation contexts.

One would need to pick one of the accepted presentation contexts and use the id of that one in subsequent interactions.

Suggested change
let pc_selected = if let Some(pc) = scu
.presentation_contexts()
.iter()
.find(|pc| transfer_syntax == &pc.transfer_syntax)
{
pc.clone()
} else {
eprintln!("Could not choose a transfer syntax");
let _ = scu.abort();
std::process::exit(-2);
};

/// verbose mode
#[structopt(short = "v")]
verbose: bool,
/// the DICOM file to store
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This made sense in the store SCU, but not anymore in the move SCU, since the application might not have the objects it wants to move in the first place. Instead, we can follow the approach done by other tools (e.g. DCMTK's movescu), and declare that the input file represents a query object.

Suggested change
/// the DICOM file to store
/// the DICOM query file

let sop_instance_uid = &meta.media_storage_sop_instance_uid;
let transfer_syntax = "1.2.840.10008.1.2";

let retrieve_level = "STUDY ";
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had overlooked this until I actually tried to run the application. The retrieval level should be fetched from the query file (QueryRetrieveLevel (0008,0052)), and only the attributes listed therein should be considered. The study instance UID or the series instance UID might not even be present.

obj
}

fn create_iod(
Copy link
Owner

@Enet4 Enet4 Mar 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once we're upfront that the input file is already a query file, there does not seem to be a reason for this function to exist other than to map one query object (from the file) into another query object. It should probably just be removed.

@Enet4 Enet4 marked this pull request as draft October 30, 2021 21:21
@Enet4
Copy link
Owner

Enet4 commented Mar 13, 2024

I'm afraid that this has diverged too much from the base project. It will need to be rebuilt from scratch, maybe after #463 so that we can couple the move SCU with a local store SCP.

@Enet4 Enet4 closed this Mar 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants